//
//  ZLStringExtension.swift
//  ZLExtension
//
//  Created by 赵振磊 on 2023/1/8.
//

import CommonCrypto

//MARK: 格式化
public extension String {
    /// md5
    func zl_md5() -> String {
        let str = self.cString(using: String.Encoding.utf8)
        let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        CC_MD5(str!, strLen, result)
        let hash = NSMutableString()
        for i in 0..<digestLen {
            hash.appendFormat("%02x", result[i])
        }
        result.deallocate()
        return hash as String
    }
    /// 获取Date
    func zl_toDate(format: String = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX") -> Date? {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = format
        let date = dateFormatter.date(from: self)
        return date
    }
    /// 连接编码
    func zl_urlEncoding() -> String {
        let url = self.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
        return url!
    }
    /// base64
    func zl_base64_encode() -> String? {
        if let data = self.data(using: .utf8) {
            return data.base64EncodedString()
        }
        return nil
    }
    /// base64
    func zl_base64_decode() -> String? {
        if let data = Data(base64Encoded: self),
           let decodedString = String(data: data, encoding: .utf8) {
            return decodedString
        }
        return nil
    }
}

//MARK: 计算
public extension String {
    /// 计算尺寸
    func zl_size(maxSize: CGSize, fontSize: CGFloat) -> CGSize {
        let str: NSString = self as NSString
        let rect = str.boundingRect(with: maxSize,
                                    options: NSStringDrawingOptions.usesLineFragmentOrigin,
                                    attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: fontSize)],
                                    context: nil)
        return CGSize(width: ceil(rect.width), height: ceil(rect.height))
    }
    /// 计算宽度
    func zl_width(fontSize: CGFloat) -> CGFloat {
        return self.zl_size(maxSize: CGSize(width: CGFloat(MAXFLOAT), height: fontSize), fontSize: fontSize).width
    }
    /// 计算高度
    func zl_height(fontSize: CGFloat) -> CGFloat {
        return self.zl_size(maxSize: CGSize(width: fontSize, height: CGFloat(MAXFLOAT)), fontSize: fontSize).height
    }
}

//MARK: 操作
public extension String {
    /// 根据开始位置和长度截取字符串
    func zl_subString(local: Int, length: Int) -> String {
        if (local > count || local < 0) { return self }
        let start = index(startIndex, offsetBy: local)
        if (local + length) > count {
            return String(self[start..<endIndex])
        }
        let end = index(start, offsetBy:length)
        return String(self[start..<end])
    }
    /// 从指定位置截取到最后
    func zl_subString(from: Int) -> String {
        return self.zl_subString(local: from, length: count)
    }
    /// 从开始截取到指定位置
    func zl_subString(to: Int) -> String {
        return self.zl_subString(local: 0, length: to)
    }
    /// 移除
    func zl_remove(local: Int, length: Int) -> String {
        var startIndex = local
        if startIndex < 0 { startIndex = 0 }
        if startIndex > count { startIndex = count }
        let start = self.zl_subString(to: startIndex)
        var endIndex = local + length
        if endIndex < 0 { endIndex = 0 }
        if endIndex > count { endIndex = count }
        let end = self.zl_subString(from: endIndex)
        return start + end
    }
    /// 从指定位置移除到最后
    func zl_remove(from: Int) -> String {
        return self.zl_remove(local: from, length: count)
    }
    /// 从开始移除到指定位置
    func zl_remove(to: Int) -> String {
        return self.zl_remove(local: 0, length: to)
    }
    /// 字符串查找
    func zl_ranges(string: String) -> [NSRange] {
        do {
            let regular = try NSRegularExpression(pattern: NSRegularExpression.escapedPattern(for: string), options: .caseInsensitive)
            let result = regular.matches(in: self, options: [], range: NSRange(location: 0, length: self.count))
            return result.map { $0.range }
        } catch let error {
            debugPrint("zl_ranges \(error)")
            return []
        }
    }
}

//MARK: 检测
public extension String {
    /// 检查邮箱格式
    func zl_checkEmail() -> Bool {
        let emailRegex: String = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
        let emailTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        return emailTest.evaluate(with: self)
    }
    // 校验验证码
    func zl_checkAutoCode() -> Bool {
        let emailRegex: String = "[a-zA-Z0-9._%+-]+"
        let emailTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        return emailTest.evaluate(with: self)
    }
    /// 校验身份证
    func checkIdCard(idCard:String) ->Bool {
        let pattern = "(^[0-9]{15}$)|([0-9]{17}([0-9]|X)$)";
        let pred = NSPredicate(format: "SELF MATCHES %@", pattern)
        let isMatch:Bool = pred.evaluate(with: idCard)
        return isMatch;
    }
    //// 检查用户名
    func zl_checkUserName() -> Bool {
        let pattern = "^[a-zA-Z\\u4E00-\\u9FA5]{1,20}"
        let pred = NSPredicate(format: "SELF MATCHES %@", pattern)
        let isMatch: Bool = pred.evaluate(with: self)
        return isMatch
    }
    /// 检密码
    func zl_checkPWD() -> Bool {
        let regex = "^[A-Za-z0-9\\^\\$\\.\\+\\*_@!#%&~=-]{6,32}$"
        let predicate = NSPredicate(format: "SELF MATCHES %@", regex)
        let isMatch:Bool = predicate.evaluate(with: self)
        return isMatch
    }
    /// 检查支付密码
    func zl_checkPayPWD() -> Bool {
        let regex = "[0-9._%+-]{6}"
        let emailTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", regex)
        return emailTest.evaluate(with: self)
    }
    /// 校验手机号
    func zl_checkMobile() -> Bool {
        /**
         * 手机号码
         * 移动：134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
         * 联通：130,131,132,152,155,156,185,186
         * 电信：133,1349,153,180,189,181(增加)
         */
        let MOBIL = "^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
        /**
         * 中国移动：China Mobile
         * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
         */
        let CM = "^1(34[0-8]|(3[5-9]|5[017-9]|8[2378])\\d)\\d{7}$";
        /**
         * 中国联通：China Unicom
         * 130,131,132,152,155,156,185,186
         */
        let CU = "^1(3[0-2]|5[256]|8[56])\\d{8}$";
        /**
         * 中国电信：China Telecom
         * 133,1349,153,180,189,181(增加)
         */
        let CT = "^1((33|53|8[019])[0-9]|349)\\d{7}$";
        let regextestmobile = NSPredicate(format: "SELF MATCHES %@", MOBIL)
        let regextestcm = NSPredicate(format: "SELF MATCHES %@", CM)
        let regextestcu = NSPredicate(format: "SELF MATCHES %@", CU)
        let regextestct = NSPredicate(format: "SELF MATCHES %@", CT)
        if regextestmobile.evaluate(with: self)||regextestcm.evaluate(with: self)||regextestcu.evaluate(with: self)||regextestct.evaluate(with: self) {
            return true
        }
        return false
    }
    /// 校验验证码
    func zl_checkAuthCode() -> Bool {
        let pattern = "^([0-9]){6}"
        let pred = NSPredicate(format: "SELF MATCHES %@", pattern)
        let isMatch: Bool = pred.evaluate(with: self)
        return isMatch;
    }
    /// 检测是否为中文
    func zl_checkChinese() -> Bool {
        let inputString = "[\u{4e00}-\u{9fa5}]+"
        let predicate = NSPredicate(format: "SELF MATCHES %@", inputString)
        let chinese = predicate.evaluate(with: self)
        return chinese
    }
    /// 校验是否是数字
    func zl_checkNumber() -> Bool {
        let emailRegex: String = "[a-zA-Z]"
        let emailTest: NSPredicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)
        return emailTest.evaluate(with: self)
    }
}

